package com.ruoyi.log.aspectj;

import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.framework.manager.AsyncManager;
import com.ruoyi.log.domain.SysVisitLog;
import com.ruoyi.log.domain.SysVisitTimeLog;
import com.ruoyi.log.manager.factory.AsyncLogFactory;

import com.ruoyi.log.utils.KeysCollector;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Map;

/**
 * @program: ruoyi
 * @description: 登录日志切面
 * @author: Abner
 * @create: 2021-10-19 08:07
 */
@Aspect
@Component
public class VisitLogAspect {
    private static final Logger log = LoggerFactory.getLogger(VisitLogAspect.class);
    @Autowired
    private RedisCache redisService;


    /**
     * 处理完请求后执行
     *
     * @param joinPoint 切点
     */
    @AfterReturning(pointcut = "@annotation(com.ruoyi.log.annotation.VisitLog)", returning = "jsonResult")
    public void doAfterReturning(JoinPoint joinPoint, Object jsonResult) {
        handleProfilerLog(joinPoint, null, jsonResult);

    }

    /**
     * 拦截异常操作
     *
     * @param joinPoint 切点
     * @param e         异常
     */
    @AfterThrowing(value = "@annotation(com.ruoyi.log.annotation.VisitLog)", throwing = "e")
    public void doAfterThrowing(JoinPoint joinPoint, Exception e) {
        handleProfilerLog(joinPoint, e, null);

    }

    protected void handleProfilerLog(final JoinPoint joinPoint, final Exception e, Object o) {

        try {
            //获取请求信息
            String appId = ServletUtils.getRequest().getParameter("appId");
            String token =ServletUtils.getRequest().getParameter("token");
            String uri = ServletUtils.getRequest().getRequestURI();
            //封装数据
            SysVisitLog sysVisitLog = new SysVisitLog();
            sysVisitLog.setAppId(Long.valueOf(appId));
            sysVisitLog.setVisitUrl(uri);
            sysVisitLog.setTokenKey(token);
            //获取当前缓存中对象
            String appRedisKey = "app:" + appId+":"+token;
            String visitKey = appId + ":" + uri+":"+token;
            Map<String, Object> appMap = redisService.getCacheMap(appRedisKey);
            //app用户在缓存中存在，不是第一次访问
            if (appMap.size()>0) {
                Object visitValue = appMap.get(visitKey);
                //是否访问过，更新缓存
                if (visitValue != null) {
                    Long count = Long.valueOf(visitValue.toString());
                    count++;
                    KeysCollector.addKey(appRedisKey, visitKey, 4, count);
                }
            }else {
                //url是当前app用户第一次访问
                KeysCollector.addKey(appRedisKey, visitKey, 4, 1L);

                SysVisitTimeLog sysVisitTimeLog = new SysVisitTimeLog();
                sysVisitTimeLog.setAppId(Long.valueOf(appId));
                sysVisitTimeLog.setTokenKey(token);
                AsyncManager.me().execute(AsyncLogFactory.recordVisitTime(sysVisitTimeLog));
            }
            //设置redis的过期时间
            String className = joinPoint.getTarget().getClass().getName();
            String methodName = joinPoint.getSignature().getName();
            sysVisitLog.setMethod(className + "." + methodName + "()");
            AsyncManager.me().execute(AsyncLogFactory.recordOper(sysVisitLog));
        } catch (Exception exp) {
            log.error("异常信息:{}", exp.getMessage());
            exp.printStackTrace();
        }


    }


}
